package com.sale.auth.controller;

import com.sale.auth.form.*;
import com.sale.auth.service.SysLoginService;
import com.sale.common.core.constant.CacheConstants;
import com.sale.common.core.constant.Constants;
import com.sale.common.core.domain.R;
import com.sale.common.core.exception.user.CaptchaExpireException;
import com.sale.common.core.utils.MessageUtils;
import com.sale.common.core.utils.StringUtils;
import com.sale.common.core.web.controller.BaseController;
import com.sale.common.redis.utils.RedisUtils;
import com.sale.common.sms.core.SmsTemplate;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * token 控制
 *
 * @author Lion Li
 */
@Validated
@RequiredArgsConstructor
@RestController
public class TokenController extends BaseController {

    private final SysLoginService sysLoginService;

    @Resource
    private SmsTemplate smsTemplate; // 可以使用
    // spring注入

    /**
     * 官网通过手机号注册进销存系统
     */
    @PostMapping("/SaasRegister")
    public R<Map<String, Object>> sysLoginService(@RequestBody SaasRegisterVo saasRegisterVo){
        Map<String, Object> map =  sysLoginService.sysLoginService(saasRegisterVo);
        return R.ok(map);
    }

    /**
     * 手机号注册
     */
    @PostMapping("/phoneRegister")
    public R<Void> phoneRegister(@Validated @RequestBody PhoneRegisterBody phoneRegisterBody){
       sysLoginService.phoneRegister(phoneRegisterBody);
        return R.ok();
    }

    /**
     * 注册保存账套信息
     */
    @PostMapping("/saveAccount")
    @Transactional(rollbackFor = Exception.class)
    public R<Map<String, Object>> saveAccount(@RequestBody AccountVo accountVo){
        String accessToken = sysLoginService.saveAccount(accountVo);
        // 接口返回信息
        Map<String, Object> rspMap = new HashMap<>();
        rspMap.put(Constants.ACCESS_TOKEN, accessToken);
        return R.ok(rspMap);
    }


    /**
     * 忘记密码
     */
    @PutMapping("/forgotPassword")
    public R<Void> forgotPassword(@RequestBody PhoneRegisterBody phoneRegisterBody){
        boolean b = sysLoginService.forgotPassword(phoneRegisterBody);
        return toAjax(b);
    }


    /**
     * 获取验证码
     */
    @GetMapping("/getCode")
    public R<Void> getCode(String phoneNumber) {
        String code = String.valueOf(new Random().nextInt(899999) + 100000);
        Map<String, String> map = new HashMap<>();
        map.put("code",code);
        smsTemplate.send(phoneNumber,"SMS_289320030",map);
        //将验证码加手机号作为key存入redis,过期时间给1分钟
        System.out.println(code);
        String key = CacheConstants.CAPTCHA_CODE_KEY + phoneNumber;
        RedisUtils.setCacheObject(key, code, Duration.ofSeconds(120));
        return R.ok();
    }

    /**
     * 验证码校验
     */
    @PostMapping("/checkSmsCode")
    public R<Map<String,Object>> checkSmsCode(@RequestBody PhoneRegisterBody phoneRegisterBody){
        String phoneNumber = phoneRegisterBody.getPhoneNumber();
        String smsCode = phoneRegisterBody.getSmsCode();

        String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phoneNumber);

        Map<String, Object> map = new HashMap<>();

        if (code == null){
            map.put("msg","验证码已过期");
            return R.fail(map);
        }
        if (!smsCode.equals(smsCode)){
            map.put("msg","验证码输入不正确");
            return R.fail(map);
        }
        return R.ok(map);
    }

    /**
     * 根据用户名和手机号判断是否第一次注册
     * @return
     */
    @GetMapping("/getIsRegistration")
    public R<Map<String,Object>> getIsRegistration(IsRegistration isRegistration){
       Map<String,Object> map = sysLoginService.getIsRegistration(isRegistration);
       return R.ok(map);
    }

    /**
     * 登录方法
     */
    @PostMapping("login")
    public R<Map<String, Object>> login(@Validated @RequestBody LoginBody form) {
        // 用户登录
        String accessToken = sysLoginService.login(form.getUsername(), form.getPassword());
        // 接口返回信息
        Map<String, Object> rspMap = new HashMap<>();
        rspMap.put(Constants.ACCESS_TOKEN, accessToken);
        return R.ok(rspMap);
    }

    /**
     * 短信登录
     *
     * @param smsLoginBody 登录信息
     * @return 结果
     */
    @PostMapping("/smsLogin")
    public R<Map<String, Object>> smsLogin(@Validated @RequestBody SmsLoginBody smsLoginBody) {

        // 生成令牌
        Map<String, Object> ajax = sysLoginService.smsLogin(smsLoginBody.getPhoneNumber(), smsLoginBody.getSmsCode());
        return R.ok(ajax);
    }

    /**
     * 邮件登录
     *
     * @param body 登录信息
     * @return 结果
     */
    @PostMapping("/emailLogin")
    public R<Map<String, Object>> emailLogin(@Validated @RequestBody EmailLoginBody body) {
        Map<String, Object> ajax = new HashMap<>();
        // 生成令牌
        String token = sysLoginService.emailLogin(body.getEmail(), body.getEmailCode());
        ajax.put(Constants.ACCESS_TOKEN, token);
        return R.ok(ajax);
    }

    /**
     * 小程序登录(示例)
     *
     * @param xcxCode 小程序code
     * @return 结果
     */
    @PostMapping("/xcxLogin")
    public R<Map<String, Object>> xcxLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode) {
        Map<String, Object> ajax = new HashMap<>();
        // 生成令牌
        String token = sysLoginService.xcxLogin(xcxCode);
        ajax.put(Constants.ACCESS_TOKEN, token);
        return R.ok(ajax);
    }

    /**
     * 登出方法
     */
    @DeleteMapping("logout")
    public R<Void> logout() {
        sysLoginService.logout();
        return R.ok();
    }

    /**
     * 用户注册
     */
    @PostMapping("register")
    public R<Void> register(@RequestBody RegisterBody registerBody) {
        // 用户注册
        sysLoginService.register(registerBody);
        return R.ok();
    }



}
